92 lines · 2.7 KB
1 ---
2 import Repo from '../../../../layouts/Repo.astro';
3 import { apiGet } from '../../../../lib/api';
4
5 const { owner, repo, ref: refParam } = Astro.params;
6 const ref = refParam || 'main';
7 const cookie = Astro.request.headers.get('cookie') || '';
8
9 let commits: any[] = [];
10 let error = '';
11
12 try {
13 const data = await apiGet(`/api/repos/${owner}/${repo}/commits/${ref}`, cookie);
14 commits = data.commits || [];
15 } catch (e: any) {
16 error = e.message;
17 }
18
19 function parseAuthor(author: string) {
20 const match = author.match(/^(.+?) <(.+?)> (\d+) ([+-]\d{4})$/);
21 if (!match) return { name: author, date: '' };
22 const timestamp = parseInt(match[3]) * 1000;
23 const date = new Date(timestamp);
24 return {
25 name: match[1],
26 date: date.toLocaleDateString('en-US', {
27 year: 'numeric',
28 month: 'short',
29 day: 'numeric',
30 }),
31 };
32 }
33 ---
34
35 <Repo owner={owner!} repo={repo!} activeTab="commits" ref={ref}>
36 {error && <div class="flash-error">{error}</div>}
37
38 <h2 style="font-size: 1rem; margin-bottom: 16px; color: var(--text-muted);">
39 Commits on <strong style="color: var(--text);">{ref}</strong>
40 </h2>
41
42 <div class="commit-list">
43 {commits.map((commit: any) => {
44 const { name, date } = parseAuthor(commit.author);
45 const shortSha = commit.sha.slice(0, 7);
46 const firstLine = commit.message.split('\n')[0];
47 return (
48 <div style="
49 display: flex;
50 justify-content: space-between;
51 align-items: center;
52 padding: 12px 16px;
53 border: 1px solid var(--border);
54 border-bottom: none;
55 background: var(--bg-secondary);
56 font-size: 0.875rem;
57 " class="commit-row">
58 <div style="min-width: 0; flex: 1;">
59 <div style="font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
60 <a href={`/${owner}/${repo}/commit/${commit.sha}`} style="color: var(--text);">
61 {firstLine}
62 </a>
63 </div>
64 <div style="color: var(--text-muted); font-size: 0.8125rem; margin-top: 2px;">
65 {name} committed on {date}
66 </div>
67 </div>
68 <div style="flex-shrink: 0; margin-left: 16px;">
69 <a
70 href={`/${owner}/${repo}/commit/${commit.sha}`}
71 class="btn"
72 style="font-family: var(--font-mono); font-size: 0.75rem; padding: 2px 10px;"
73 >
74 {shortSha}
75 </a>
76 </div>
77 </div>
78 );
79 })}
80 </div>
81 </Repo>
82
83 <style>
84 .commit-row:first-child {
85 border-radius: var(--radius) var(--radius) 0 0;
86 }
87 .commit-row:last-child {
88 border-bottom: 1px solid var(--border) !important;
89 border-radius: 0 0 var(--radius) var(--radius);
90 }
91 </style>
92